﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using devtm.AutoMapper.CustomCode.TemplateAdd;
using System.ComponentModel.Composition;
using Microsoft.VisualStudio.Modeling.Diagrams;
using CodeDomHelper.Types;
using devtm.Editor.TypeSelector;

namespace devtm.AutoMapper
{
    public partial class MappingModel
    {


      

        #region Namespace

        string NamespaceStr = string.Empty;
        internal string GetNamespaceValue()
        {

            if (!string.IsNullOrEmpty(NamespaceStr))
                return NamespaceStr;

            return NamespaceStr = Store2DTE.GetDefaultNamespace(this.Store);

        }



        internal void SetNamespaceValue(string newValue)
        {
            NamespaceStr = newValue;
        }

        #endregion


        public HashSet<String> GetNamespaces
        {
            get
            {
                HashSet<String> namespaces = new HashSet<string>();

                namespaces.Add(Namespace);

                foreach (UsingNamespace item in Namespaces)
                    if (!namespaces.Contains(item.Fullname))
                        namespaces.Add(item.Fullname);                

                return namespaces;
            }
        }


        //internal IEnumerable<Type> GetTypes()
        //{

        //    HashSet<string> namespaces = GetNamespaces;

        //    foreach (Type item in ContainerTypes.GetFromReference(Store, namespaces))            
        //        yield return item;

        //    foreach (Type item in  ContainerTypes.GetFromSolution<Object>(Store, namespaces))
        //        yield return item;

        //}


        // System.Collections.Generic.IEnumerable`1[[MappingTest.Sources.ClassTest3, MappingTest, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]
        internal Type FindType(string typeName)
        {

            return Helpers.FindType(typeName, Store, GetNamespaces);

        }


        internal TypeElement FindTypeElementByClass(string type)
        {

            foreach (var item in this.Elements)
                if (item.AssemblyQualifiedName == type)
                    return item;

            return null;
        }

        internal Mapper FindMapperFor(string typeSource, string typeTarget)
        {

            foreach (var item in this.Mappers)
            
                if (item.MappingSource != null && item.MappingDestination != null)

                    if (item.MappingSource.TypeElement.AssemblyQualifiedName == typeSource && item.MappingDestination.TypeElement.AssemblyQualifiedName == typeTarget)
                     
                        return item;

            
            return null;
        }

        internal Mapper FindMapperFor(string typeSource)
        {

            foreach (var item in this.Mappers)
                if (item.MappingSource != null && item.MappingDestination != null)
                    if (item.MappingSource.TypeElement.AssemblyQualifiedName == typeSource)
                        return item;

            return null;
        }

        internal TypeElement FindElementFor(string type)
        {

            foreach (TypeElement item in this.Elements)
                if (item.AssemblyQualifiedName == type)                    
                        return item;

            return null;
        }

        internal void CreateMapper()
        {

            HashSet<string> namespaces = GetNamespaces;
            List<Type> lst = ContainerTypes.GetFromReference(Store, namespaces).ToList();

            try
            {
                lst.AddRange(ContainerTypes.GetFromSolution<Object>(Store, namespaces));
            }
            catch (Exception)
            {
                
                throw;
            }

            AddMapRoot frm = new AddMapRoot();
            frm.SetList(lst.Where(c => c.IsClass || c.IsInterface || (c.IsValueType && !c.IsEnum && !c.IsPrimitive)).ToList());

            if (frm.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                NewMapperHelper.CreateMapper(this, frm.SourceType.AssemblyQualifiedName, frm.TargetType.AssemblyQualifiedName, true, null);

                if (frm.CreateBack)
                    NewMapperHelper.CreateMapper(this, frm.TargetType.AssemblyQualifiedName, frm.SourceType.AssemblyQualifiedName, true, null);
            }


        }
    }
}
